

package main

import (
	"ry/mat"
	"fmt"
	"runtime"
	"image"
	"ry/imageserver"
	"ry/kernel"
)



var Cells [N*N]cell
var Buffer [N*N]cell
var Grid mat.Grid = mat.New (N,N)
var Agents [NAGENTS]agent

func (a *agent) Round () (i,j int) {

	i = int (a.x)
	j = int (a.y)
	return
}

func (a *agent) Wrap () {

	n := float64(N)

	for a.x < 0 {
		a.x += n
	}
	for a.x >= n {
		a.x -= n
	}
	for a.y < 0 {
		a.y += n
	}
	for a.y >= n {
		a.y -= n
	}
}

func InitAgents() {

	for k := 0; k < NAGENTS; k++ {
		Agents[k].Init ()
		Agents[k].Wrap()
	}
}

func InitCells() {

	rows, cols := Grid.Dims ()
	
	
	
	for i := 0; i < rows; i++ {
		for j := 0; j < cols; j++ {
			Cells [Grid.Index (i,j)].Init (i,j)
		}
	}
}

func UpdateAgents() {

	for k, a := range Agents {
		i,j := a.Round ()
		Agents[k].Update(Grid.Select(i-R,j-R,i+R,j+R), 0.1)
	}
}

func abs(i int) int {

	if i < 0 {
		return -i
	}

	return i
}

func UpdateCells() {

	//buf := m.Medium.Copy()

	rows, cols := Grid.Dims ()
	
	copy (&Buffer, &Cells)

	done := kernel.Launch (rows, cols, 
		func (i,j int) bool {
			Buffer[Grid.Index (i,j)].Update (Grid.Select (i-R,j-R, i+R,j+R), 0.1)
			return true
		})
		
	_ = <-done
	
	copy (&Cells, &Buffer)
}

func Draw(out *image.RGBA64) {

	rows, cols := Grid.Dims ()
	
	for i := 0; i < rows; i++ {
		for j := 0; j < cols; j++ {
			out.Set (i,j, Cells [Grid.Index (i,j)].Color ())
		}
	}
	
	white := image.RGBAColor{255,255,255,255}
	
	for k := 0; k < len (Agents); k++ {
		i,j := Agents [k].Round ()
		out.Set (i,j, white)
	}
}

func main () {

	runtime.GOMAXPROCS (2)

	fmt.Println ("initializing...")

	img := image.NewRGBA64 (N,N)
	
	InitCells()
	InitAgents()

	fmt.Println ("listening...")

	imgch := make (chan image.Image)
	done := make (chan bool)
	
	go func () { done <- true } ()

	go imageserver.ListenAndServe (":1234", imgch, done)

	fmt.Println ("running...")
	for {
		fmt.Print (".")
		UpdateCells()
		UpdateAgents()
		_ = <-done
		Draw(img)
		imgch <- img
	}
	
	fmt.Println ("done.")
}
